<!--
***********************************************************************************************
CLRTest.Execute.Bash.targets

WARNING:  DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
          created a backup copy.  Incorrect changes to this file will make it
          impossible to load or build your projects from the command-line or the IDE.

This file contains the logic for providing Execution Script generation.

WARNING:   When setting properties based on their current state (for example:
           <Foo Condition="'$(Foo)'==''>Bar</Foo>).  Be very careful.  Another script generation
           target might be trying to do the same thing.  It's better to avoid this by instead setting a new property.

           Additionally, be careful with itemgroups.  Include will propagate outside of the target too!

***********************************************************************************************
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <!--
    Target: GetExecuteShFullPath
    Return Executed Sh Relative Full Path
    We can use this target get its toRun Project's Sh Full Path to avoid hard-code
  -->
  <Target
    Name="GetExecuteShFullPath"
    Returns="$(ExecuteShFullPath)">
    <PropertyGroup Condition="$(GenerateRunScript)">
      <ExecuteShFullPath>$(OutputPath)$(AssemblyName).sh</ExecuteShFullPath>
    </PropertyGroup>
    <!-- In order to avoid the overhead of calling MSBuild (as it may result in chains of MSBuild calls) I am assuming the extension in this circumstance. -->
    <PropertyGroup Condition="$(CLRTestProjectToRun) != '' AND $(GenerateRunScript)">
      <ExecuteShFullPath>$(OutputPath)$([System.IO.Path]::GetFilenameWithoutExtension(&quot;$(CLRTestProjectToRun)&quot;)).dll</ExecuteShFullPath>
    </PropertyGroup>
    <PropertyGroup Condition="!$(GenerateRunScript)">
      <ExecuteShFullPath>$(OutputPath)$(AssemblyName).$(OutputType.ToLower())</ExecuteShFullPath>
    </PropertyGroup>
  </Target>


  <!--
  *******************************************************************************************
  TARGET: GenerateExecutionScriptInternal

  For tests that "run" we will generate an execution script that wraps any arguments or other
  goo.  This allows generated .lst files to be very simple and reusable to invoke any "stage"
  of test execution.

  Notice this is hooked up to run after targets that generate the stores that are marked with GenerateScripts metadata.
  Note also that this means it will run after the first of such targets.
  -->
  <Target Name="GenerateBashExecutionScript"
    Inputs="$(MSBuildProjectFullPath)"
    Outputs="$(OutputPath)\$(AssemblyName).sh"
    DependsOnTargets="$(BashScriptSnippetGen);GetIlasmRoundTripBashScript;GetSuperPMICollectionBashScript">

    <Message Text="Project depends on $(_CLRTestToRunFileFullPath)." Condition="'$(_CLRTestNeedsProjectToRun)' == 'True'" />

    <PropertyGroup>
      <IncompatibleTestBashScriptExitCode>0</IncompatibleTestBashScriptExitCode>
      <CoreRunArgs>@(RuntimeHostConfigurationOption -> '-p &quot;%(Identity)=%(Value)&quot;', ' ')</CoreRunArgs>
      <IosTestTarget Condition="'$(TargetOS)' == 'iossimulator'">ios-simulator-64</IosTestTarget>
      <IosTestTarget Condition="'$(TargetOS)' == 'ios'">ios-device</IosTestTarget>
      <IosTestTarget Condition="'$(TargetOS)' == 'tvossimulator'">tvos-simulator</IosTestTarget>
      <IosTestTarget Condition="'$(TargetOS)' == 'tvos'">tvos-device</IosTestTarget>

      <BashCLRTestEnvironmentCompatibilityCheck Condition="'$(GCStressIncompatible)' == 'true'"><![CDATA[
$(BashCLRTestEnvironmentCompatibilityCheck)
if [ ! -z "$DOTNET_GCStress" ]
then
  echo SKIPPING EXECUTION BECAUSE DOTNET_GCStress IS SET
  exit $(IncompatibleTestBashScriptExitCode)
fi
      ]]></BashCLRTestEnvironmentCompatibilityCheck>
      <BashCLRTestEnvironmentCompatibilityCheck Condition="'$(UnloadabilityIncompatible)' == 'true'"><![CDATA[
$(BashCLRTestEnvironmentCompatibilityCheck)
if [ ! -z "$RunInUnloadableContext" ]
then
  echo SKIPPING EXECUTION BECAUSE the test is incompatible with unloadability
  exit $(IncompatibleTestBashScriptExitCode)
fi
      ]]></BashCLRTestEnvironmentCompatibilityCheck>
      <BashCLRTestEnvironmentCompatibilityCheck Condition="'$(TieringTestIncompatible)' == 'true'"><![CDATA[
$(BashCLRTestEnvironmentCompatibilityCheck)
if [ ! -z "$RunTieringTest" ]
then
  echo SKIPPING EXECUTION BECAUSE the test is incompatible with the tiering test harness
  exit $(IncompatibleTestBashScriptExitCode)
fi
      ]]></BashCLRTestEnvironmentCompatibilityCheck>
      <BashCLRTestEnvironmentCompatibilityCheck Condition="'$(JitOptimizationSensitive)' == 'true' And '$(RuntimeFlavor)' != 'mono' and '$(TestBuildMode)' != 'nativeaot'">
    <![CDATA[
$(BashCLRTestEnvironmentCompatibilityCheck)
if [[ ( ! -z "$DOTNET_JitStress" ) || ( ! -z "$DOTNET_JitStressRegs" ) || ( ! -z "$DOTNET_JITMinOpts" ) || ( ! -z "$DOTNET_TailcallStress" ) ]]
then
  echo "SKIPPING EXECUTION BECAUSE ONE OR MORE OF (DOTNET_JitStress, DOTNET_JitStressRegs, DOTNET_JITMinOpts, DOTNET_TailcallStress) IS SET"
  exit $(IncompatibleTestBashScriptExitCode)
fi
if [[ "$DOTNET_TieredCompilation" != "0" ]]
then
  echo "SKIPPING EXECUTION BECAUSE DOTNET_TieredCompilation has not been disabled and this test is marked JitOptimizationSensitive"
  exit $(IncompatibleTestBashScriptExitCode)
fi
      ]]></BashCLRTestEnvironmentCompatibilityCheck>
      <BashCLRTestEnvironmentCompatibilityCheck Condition="'$(HeapVerifyIncompatible)' == 'true'"><![CDATA[
$(BashCLRTestEnvironmentCompatibilityCheck)
if [ ! -z "$DOTNET_HeapVerify" ]
then
  echo SKIPPING EXECUTION BECAUSE DOTNET_HeapVerify IS SET
  exit $(IncompatibleTestBashScriptExitCode)
fi
      ]]></BashCLRTestEnvironmentCompatibilityCheck>
      <BashCLRTestEnvironmentCompatibilityCheck Condition="'$(IlasmRoundTripIncompatible)' == 'true'"><![CDATA[
$(BashCLRTestEnvironmentCompatibilityCheck)
if [ ! -z "$RunningIlasmRoundTrip" ]
then
  echo SKIPPING EXECUTION BECAUSE RunningIlasmRoundTrip IS SET
  exit $(IncompatibleTestBashScriptExitCode)
fi
      ]]></BashCLRTestEnvironmentCompatibilityCheck>
      <BashCLRTestEnvironmentCompatibilityCheck Condition="'$(SynthesizedPgoIncompatible)' == 'true'"><![CDATA[
$(BashCLRTestEnvironmentCompatibilityCheck)
if [ ! -z "$CrossGen2SynthesizePgo" ]
then
  echo SKIPPING EXECUTION BECAUSE CrossGen2SynthesizePgo IS SET
  exit $(IncompatibleTestBashScriptExitCode)
fi
      ]]></BashCLRTestEnvironmentCompatibilityCheck>

      <BashCLRTestExitCodePrep Condition="$(_CLRTestNeedsToRun)">
<![CDATA[
export CLRTestExpectedExitCode=$(CLRTestExitCode)
echo BEGIN EXECUTION]]>
      </BashCLRTestExitCodePrep>

      <BashCLRTestArgPrep Condition=" '$(CLRTestExecutionArguments)'!='' ">
<![CDATA[if [ -z ${CLRTestExecutionArguments+x} ]%3B then CLRTestExecutionArguments=($(CLRTestExecutionArguments))%3B fi]]>
      </BashCLRTestArgPrep>

      <!-- By default, be prepared to do a full check -->
      <BashCLRTestExitCodeCheck><![CDATA[
echo Expected: $CLRTestExpectedExitCode
echo Actual: $CLRTestExitCode

if [ -z ${CLRTestExitCode+x} ]
then
  echo END EXECUTION - FAILED
  exit 1
fi

if [ $CLRTestExitCode -ne $CLRTestExpectedExitCode ]
then
  echo END EXECUTION - FAILED
  exit 1
else
  echo END EXECUTION - PASSED
  exit 0
fi
      ]]></BashCLRTestExitCodeCheck>
    </PropertyGroup>

    <ItemGroup Condition="$(_CLRTestNeedsToRun)">
      <Clean Include="$(OutputPath)\$(AssemblyName).sh"/>

      <BashCLRTestExecutionScriptArgument Include="debug">
        <HasParam>true</HasParam>
        <ParamText>=*</ParamText> <!-- Bash specific -->
        <Separator>=</Separator>
        <ParamName>debuggerFullPath</ParamName>
        <Command><![CDATA[        export _DebuggerFullPath="${1#*=}"
        if [ ! -f "$_DebuggerFullPath" ]
        then
            echo "The Debugger FullPath %5C%22${_DebuggerFullPath}%5C%22 does not exist"
            usage
        fi]]></Command>
        <Description>Run testcases under debugger.</Description>
      </BashCLRTestExecutionScriptArgument>

      <BashCLRTestExecutionScriptArgument Include="debug">
        <HasParam>true</HasParam>
        <ParamText></ParamText> <!-- Bash specific -->
        <Separator>%20</Separator>
        <ParamName>debuggerFullPath</ParamName>
        <Command><![CDATA[        export _DebuggerFullPath="$2"
        shift
        if [ ! -f "$_DebuggerFullPath" ]
        then
            echo "The Debugger FullPath %5C%22${_DebuggerFullPath}%5C%22 does not exist"
            usage
        fi]]></Command>
        <Description>Run testcases under debugger.</Description>
      </BashCLRTestExecutionScriptArgument>

      <BashCLRTestExecutionScriptArgument Include="coreroot">
        <HasParam>true</HasParam>
        <ParamText>=*</ParamText> <!-- Bash specific -->
        <Separator>=</Separator>
        <ParamName>coreRootFullPath</ParamName>
        <Command><![CDATA[        export CORE_ROOT="${1#*=}"]]></Command>
        <Description>Set CORE_ROOT to the specified value before running the test.</Description>
      </BashCLRTestExecutionScriptArgument>

      <BashCLRTestExecutionScriptArgument Include="coreroot">
        <HasParam>true</HasParam>
        <ParamText></ParamText> <!-- Bash specific -->
        <Separator>%20</Separator>
        <ParamName>coreRootFullPath</ParamName>
        <Command><![CDATA[        export CORE_ROOT="$2"
        shift]]></Command>
        <Description>Set CORE_ROOT to the specified value before running the test.</Description>
      </BashCLRTestExecutionScriptArgument>

      <BashCLRTestExecutionScriptArgument Include="e;env">
        <HasParam>true</HasParam>
        <ParamText>=*</ParamText> <!-- Bash specific -->
        <Separator>=</Separator>
        <ParamName>dotenvFullPath</ParamName>
        <Command><![CDATA[        export __DotEnv="${1#*=}"
        if [ ! -f "$__DotEnv" ]
        then
            echo "The dotenv file FullPath %5C%22${__DotEnv}%5C%22 does not exist"
            usage
        fi
        export __DotEnvArg=-e ${__DotEnv}]]></Command>
        <Description>A dotenv file to pass to corerun to set environment variables for the test run.</Description>
      </BashCLRTestExecutionScriptArgument>

      <BashCLRTestExecutionScriptArgument Include="e;env">
        <HasParam>true</HasParam>
        <ParamText></ParamText> <!-- Bash specific -->
        <Separator>%20</Separator>
        <ParamName>dotenvFullPath</ParamName>
        <Command><![CDATA[        export __DotEnv="$2"
        shift
        if [ ! -f "$__DotEnv" ]
        then
            echo "The dotenv file FullPath %5C%22${__DotEnv}%5C%22 does not exist"
            usage
        fi
        export __DotEnvArg=-e ${__DotEnv}]]></Command>
        <Description>A dotenv file to pass to corerun to set environment variables for the test run.</Description>
      </BashCLRTestExecutionScriptArgument>

      <BashCLRTestExecutionScriptArgument Include="usewatcher">
        <HasParam>false</HasParam>
        <Command><![CDATA[        _RunWithWatcher=1]]></Command>
        <Description>Run the tests using the test watcher.</Description>
      </BashCLRTestExecutionScriptArgument>
    </ItemGroup>

      <PropertyGroup>
          <ReflectionRootsXml>$(AssemblyName).reflect.xml</ReflectionRootsXml>
          <BashLinkerTestLaunchCmds>
              <![CDATA[
# Linker commands

LinkBin=__Link
Assemblies="-a System.Private.CoreLib"
ReflectionRoots=

shopt -s nullglob

if [ ! -z "$DoLink" ];
then
  if [ ! -x "$ILLINK" ];
  then
    echo "Illink executable [$ILLINK] Invalid"
    exit 1
  fi

  # Clean up old Linked binaries, if any
  rm -rf $LinkBin

  # Remove Native images, since the goal is to run from Linked binaries
  rm -f *.ni.*

  # Use hints for reflection roots, if provided in $(ReflectionRootsXml)
  if [ -f $(ReflectionRootsXml) ];
  then
    ReflectionRoots="-x $(ReflectionRootsXml)"
  fi

  # Include all .exe files in this directory as entry points (some tests had multiple .exe file modules)
  for bin in *.exe *.dll;
  do
    Assemblies="$Assemblies -a ${bin%.*}"
  done

  # Run dotnet-linker
  # Run the Linker such that all assemblies except System.Private.Corlib.dll are linked
  # Debug symbol generation needs some fixes, and is currently omitted.
  # Once this is fixed, add -b true option.
  echo "$ILLINK -out $LinkBin -d $CORE_ROOT -c link -l none -t $Assemblies $ReflectionRoots"
  $ILLINK -out $LinkBin -d $CORE_ROOT -c link -l none -t $Assemblies $ReflectionRoots
  ERRORLEVEL=$?
  if [  $ERRORLEVEL -ne 0 ]
  then
    echo ILLINK FAILED $ERRORLEVEL
    if [ -z "$KeepLinkedBinaries" ];
    then
      rm -rf $LinkBin
    fi
    exit 1
  fi

  # Copy CORECLR native binaries and the test watcher to $LinkBin,
  # so that we can run the test based on that directory
  cp $CORE_ROOT/*.so $LinkBin/
  cp $CORE_ROOT/corerun $LinkBin/
  cp $CORE_ROOT/watchdog $LinkBin/

  # Copy some files that may be arguments
  for f in *.txt;
  do
    [ -e "$f" ] && cp $f $LinkBin
  done

  ExePath=$LinkBin/$(InputAssemblyName)
  export CORE_ROOT=$PWD/$LinkBin
fi
]]>
          </BashLinkerTestLaunchCmds>
          <BashLinkerTestCleanupCmds>
              <![CDATA[
# Clean up the LinkBin directories after test execution.
# Otherwise, RunTests may run out of disk space.

if [ ! -z "$DoLink" ];
then
  if [ -z "$KeepLinkedBinaries" ];
  then
    rm -rf $LinkBin
  fi
fi
]]>
          </BashLinkerTestCleanupCmds>
      </PropertyGroup>
      <PropertyGroup>
      <CLRTestRunFile Condition="'$(CLRTestIsHosted)'=='true'">"$CORE_ROOT/corerun" $(CoreRunArgs)  ${__DotEnvArg}</CLRTestRunFile>
      <WatcherRunFile>"$CORE_ROOT/watchdog" $_WatcherTimeoutMins</WatcherRunFile>

      <!-- Note that this overwrites CLRTestBashPreCommands rather than adding to it. -->
      <CLRTestBashPreCommands Condition="'$(CLRTestKind)' == 'BuildAndRun' and '$(TargetArchitecture)' == 'wasm'"><![CDATA[
# Build wasm app containing the test dll
__Command=""
if [ ! -z ${__TestDotNetCmd+x} ] %3B then
  __Command+=" $__TestDotNetCmd"
else
  __Command+=" dotnet"
fi

# workaround msbuild issue - https://github.com/dotnet/runtime/issues/74328
export DOTNET_CLI_DO_NOT_USE_MSBUILD_SERVER=1

$__Command msbuild $CORE_ROOT/wasm-test-runner/WasmTestRunner.proj /p:NetCoreAppCurrent=$(NetCoreAppCurrent) /p:TestAssemblyFileName=$(MsBuildProjectName).dll /p:TestBinDir=`pwd` $(CLRTestMSBuildArgs) || exit $?

   ]]>
      </CLRTestBashPreCommands>

      <BashCLRTestLaunchCmds Condition="'$(CLRTestKind)' == 'BuildAndRun' And '$(TargetOS)' != 'browser' And '$(TargetOS)' != 'android' And '$(TargetArchitecture)' != 'arm64'">
    <![CDATA[
$(BashLinkerTestLaunchCmds)

_DebuggerArgsSeparator=
if [[ "$_DebuggerFullPath" == *lldb* ]];
then
  _DebuggerArgsSeparator=--
elif [[ "$_DebuggerFullPath" == *gdb* ]]
then
  _DebuggerArgsSeparator=--args
fi

if [ ! -z "$CLRCustomTestLauncher" ];
then
    LAUNCHER="$CLRCustomTestLauncher $PWD/"
elif [ "$_RunWithWatcher" == 1 ];
then
    LAUNCHER="$(WatcherRunFile) $(CLRTestRunFile)"
else
    LAUNCHER="$_DebuggerFullPath $_DebuggerArgsSeparator $(CLRTestRunFile)"
fi

if [ ! -z ${RunCrossGen2+x} ]%3B then
  TakeLock
fi

echo $LAUNCHER $ExePath %24(printf "'%s' " "${CLRTestExecutionArguments[@]}")
$LAUNCHER $ExePath "${CLRTestExecutionArguments[@]}"

CLRTestExitCode=$?

if [ ! -z ${RunCrossGen2+x} ]%3B then
  ReleaseLock
fi

$(BashLinkerTestCleanupCmds)
      ]]></BashCLRTestLaunchCmds>
      <BashCLRTestLaunchCmds Condition="'$(CLRTestKind)' == 'BuildAndRun' And '$(TargetOS)' != 'browser' And '$(TargetOS)' != 'android' And '$(TargetArchitecture)' == 'arm64'">
    <![CDATA[
$(BashLinkerTestLaunchCmds)

if [ ! -z "$CLRCustomTestLauncher" ];
then
    LAUNCHER="$CLRCustomTestLauncher $PWD/"
elif [ "$_RunWithWatcher" == 1 ];
then
    LAUNCHER="$(WatcherRunFile) $(CLRTestRunFile)"
else
    LAUNCHER="$_DebuggerFullPath $_DebuggerArgsSeparator $(CLRTestRunFile)"
fi

if [ ! -z ${RunCrossGen2+x} ]%3B then
  TakeLock
fi

echo $LAUNCHER $ExePath %24(printf "'%s' " "${CLRTestExecutionArguments[@]}")
$LAUNCHER $ExePath "${CLRTestExecutionArguments[@]}"

CLRTestExitCode=$?

if [ ! -z ${RunCrossGen2+x} ]%3B then
  ReleaseLock
fi

$(BashLinkerTestCleanupCmds)
      ]]></BashCLRTestLaunchCmds>
      <BashCLRTestLaunchCmds Condition="'$(CLRTestKind)' == 'BuildAndRun' And '$(TargetOS)' == 'browser'">
      <![CDATA[
cd WasmApp
./run-v8.sh
CLRTestExitCode=$?
      ]]>
      </BashCLRTestLaunchCmds>
      <BashCLRTestLaunchCmds Condition="'$(CLRTestKind)' == 'BuildAndRun' And '$(TargetOS)' == 'android'">
      <![CDATA[
# run Android app
__Command=""
if [ ! -z ${__TestDotNetCmd+x} ] %3B then
  __Command+=" $__TestDotNetCmd"
else
  __Command+=" dotnet"
fi

if [ ! -z "$XHARNESS_CLI_PATH" ]; then
	# When running in CI, we only have the .NET runtime available
	# We need to call the XHarness CLI DLL directly via dotnet exec
	HARNESS_RUNNER="exec $XHARNESS_CLI_PATH"
else
	HARNESS_RUNNER="xharness"
fi

$__Command $HARNESS_RUNNER android run --instrumentation="net.dot.MonoRunner" --package-name="net.dot.$__Category" --output-directory="$__OutputDir" --arg=entrypoint:libname=$(MsBuildProjectName).dll --expected-exit-code=100 -v
CLRTestExitCode=$?

# Exit code of xharness is zero when tests finished successfully
CLRTestExpectedExitCode=0
      ]]>
      </BashCLRTestLaunchCmds>
      <BashCLRTestLaunchCmds Condition="'$(CLRTestKind)' == 'BuildAndRun' and ('$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvos' or '$(TargetOS)' == 'tvossimulator' or '$(TargetOS)' == 'maccatalyst')">
      <![CDATA[
__Command=""
if [ ! -z ${__TestDotNetCmd+x} ] %3B then
  __Command+=" $__TestDotNetCmd"
else
  __Command+=" dotnet"
fi

if [ ! -z "$XHARNESS_CLI_PATH" ]; then
	# When running in CI, we only have the .NET runtime available
	# We need to call the XHarness CLI DLL directly via dotnet exec
	HARNESS_RUNNER="exec $XHARNESS_CLI_PATH"
else
	HARNESS_RUNNER="xharness"
fi

$__Command $HARNESS_RUNNER apple just-run %5c
  --app="net.dot.$__Category" %5c
  --output-directory="$__OutputDir" %5c
  --set-env="MONO_APPLE_APP_ENTRY_POINT_LIB_NAME=testdir-$(MsBuildProjectName)/$(MsBuildProjectName).dll" %5c
  --set-env="MONO_APPLE_APP_ASSEMBLY_LOAD_PREFIX=testdir-$(MsBuildProjectName)" %5c
  --expected-exit-code=100 %5c
  --targets $(IosTestTarget) %5c
  -v
CLRTestExitCode=$?

# Exit code of xharness is zero when tests finished successfully
CLRTestExpectedExitCode=0
      ]]>
      </BashCLRTestLaunchCmds>
      <BashCLRTestLaunchCmds Condition="'$(CLRTestKind)' == 'RunOnly'"><![CDATA[
echo export CDPATH="$%28dirname "${BASH_SOURCE[0]}")"
export CDPATH="$%28dirname "${BASH_SOURCE[0]}")"
echo /usr/bin/env bash $(InputAssemblyName) %24(printf "'%s' " "${CLRTestExecutionArguments[@]}")
/usr/bin/env bash $(InputAssemblyName) "${CLRTestExecutionArguments[@]}"
CLRTestExitCode=$?
CLRTestExpectedExitCode=0
      ]]></BashCLRTestLaunchCmds>
    </PropertyGroup>

    <PropertyGroup>
      <BashEnvironmentVariables>
@(CLRTestBashEnvironmentVariable -> 'export %(Identity)=%(Value)', '%0a')
@(CLRTestEnvironmentVariable -> 'export %(Identity)=%(Value)', '%0a')
      </BashEnvironmentVariables>
    </PropertyGroup>

    <Message Text="MSBuildProjectDirectory:$(MSBuildProjectDirectory)" />
    <Message Text="_CLRTestToRunFileFullPath:$(_CLRTestToRunFileFullPath)"/>
    <Message Text="CLRTestRunFile:$(CLRTestRunFile)" />

    <ItemGroup>
      <_RequiredProperties Include="CLRTestRunFile">
        <Value>$(CLRTestRunFile)</Value>
      </_RequiredProperties>
    </ItemGroup>

    <!-- Raise an error if any value in _RequiredProperties is missing  -->
    <Error Condition=" '%(_RequiredProperties.Value)'=='' "
      Text="Missing required test property [%(_RequiredProperties.Identity)]. Something isn't plumbed through correctly.  Contact $(_CLRTestBuildSystemOwner)." />
    <PropertyGroup>
      <!--
      This generates the script portion to parse all of the command line arguments.
      The Command metadata for BashCLRTestExecutionScriptArgument items is executed
      when the argument is found.
      -->
      <BashCLRTestArgPrep><![CDATA[
usage()
{
    echo "Usage: $0  $(_CLRTestParamList)"
    echo
    echo "Arguments:"
@(BashCLRTestExecutionScriptArgument -> '    echo "-%(Identity)%(Separator)%(ParamName)"
    echo      "%(Description)"', '
')
    echo "-?,-h,--help    show this message"
    exit 1
}

# Parse Command Line

while [[ "$#" -gt 0 ]];
    do
        case $1 in
          -?|-h|--help|/?|/h|/help)
        usage
        %3B%3B
        @(BashCLRTestExecutionScriptArgument -> '        -%(Identity)%(ParamText)|/%(Identity)%(ParamText))
%(Command)
        %3B%3B')
        *)
        CLRTestExecutionArguments+=("${1}")
    esac
    shift
done

$(BashCLRTestArgPrep)
      ]]></BashCLRTestArgPrep>

      <CLRTestExecutionScriptHeader Condition="'$(TargetOS)' == 'android'">
        <![CDATA[
%23%21/usr/bin/env bash
set -e
      ]]></CLRTestExecutionScriptHeader>
      <CLRTestExecutionScriptHeader Condition="'$(TargetOS)' != 'android'">
        <![CDATA[
%23%21/usr/bin/env bash
      ]]></CLRTestExecutionScriptHeader>

      <!-- NOTE! semicolons must be escaped with %3B boooo -->
      <_CLRTestExecutionScriptText>
        <![CDATA[
$(CLRTestExecutionScriptHeader)
TakeLock()
{
    echo "in takeLock"
    if mkdir $LockFile%3B then
        return 2
    else
        sleep 10
        TakeLock
    fi
    echo "exiting takelock"
}

ReleaseLock()
{
    echo "in ReleaseLock"
    if [ -d "$LockFile" ]%3B then
        rm -rf "$LockFile"
        return 3
    fi
}
cd "$%28dirname "${BASH_SOURCE[0]}")"
LockFile="lock"
_RunWithWatcher=0
_WatcherTimeoutMins=10

if [[ ! -z "$__TestCollectionTimeoutMins" ]]%3B then
    _WatcherTimeoutMins=$__TestCollectionTimeoutMins
fi

# The watcher needs a bit of time to start up, capture dumps, clean up, and so on.
# Because of this, we pass a smaller timeout than the test collection one.
# For simplicity purposes, we will assume there are no work items with just
# a one-minute max timeout.
if (( $_WatcherTimeoutMins > 1 ))%3B then
    _WatcherTimeoutMins="%24((_WatcherTimeoutMins-1))"
fi

# The __TestEnv variable may be used to specify a script to source before the test.
if [ -n "$__TestEnv" ]%3B then
    source $__TestEnv
fi

$(BashCLRTestEnvironmentCompatibilityCheck)
$(BashCLRTestArgPrep)
$(BashCLRTestExitCodePrep)
$(IlasmRoundTripBashScript)
$(SuperPMICollectionBashScript)
# Allow test environment variables or precommands to override the ExePath
ExePath=$(InputAssemblyName)
export TestExclusionListPath=$CORE_ROOT/TestExclusionList.txt
$(BashEnvironmentVariables)
# PreCommands
$(CLRTestBashPreCommands)
# Launch
$(BashCLRTestLaunchCmds)
# PostCommands
$(CLRTestBashPostCommands)
$(BashCLRTestExitCodeCheck)
      ]]>
      </_CLRTestExecutionScriptText>

    </PropertyGroup>

    <PropertyGroup>
      <ExecutionBashScriptPath>$(OutputPath)/$(AssemblyName).sh</ExecutionBashScriptPath>
    </PropertyGroup>

    <!-- Write the file.
         Note: under the hood, this will rely on Environment.NewLine for line
         endings. This means that if the scripts are being generated on Windows,
         the line endings will need to be changed from CR-LF to Unix (LF) line
         endings before running the scripts on Unix platforms. In our current lab
         infra it shouldn't really matter as the execution scripts are regenerated
         in the 'test run' phase before sending the items to Helix i.o.w. at
         the point where we already know the exact targeting platform. -->
    <WriteLinesToFile
      File="$(ExecutionBashScriptPath)"
      Lines="$(_CLRTestExecutionScriptText)"
      Overwrite="true" />
    <Exec Condition="'$(SkipChmodOfGeneratedCommandScript)' != 'true'" Command="chmod +x $(ExecutionBashScriptPath)" EchoOff="true" />
  </Target>

</Project>
